/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package net.octopeer.core;

import java.io.File;
import java.io.StringReader;

import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;

import org.xml.sax.InputSource;

import net.octopeer.utilities.XMLTools;

/**
 *
 * @author andria
 */
public class Neighbor {
    private PeerNode node;
    private int rank;

    public Neighbor() {
        //
    }
    
    public Neighbor(PeerNode node, int rank) {
        this.node = node;
        this.rank = rank;
    }
    
    public void setNode(PeerNode node) {
        this.node = node;
    }
    
    public void setRank(int rank) {
        this.rank = rank;
    }
    
    public void incRank() {
        this.rank++;
    }
    
    public void decRank() {
        this.rank--;
    }
    
    public PeerNode getNode() {
        return this.node;
    }
    
    public int getRank() {
        return this.rank;
    }
    
    public Document toXMLDoc() throws Exception {
        Document doc;
        XMLTools xt = new XMLTools();        
        doc = xt.db.newDocument();
        
        Element rootEle = doc.createElement("Neighbor");

        // Node
        Element neighborNodeEle = doc.createElement("Neighbor:Node");
        
        // ID
        Element neighborNodeIDEle = doc.createElement("Neighbor:Node:ID");
        Text neighborNodeIDText = doc.createTextNode(this.node.getNodeID());
        neighborNodeIDEle.appendChild(neighborNodeIDText);
        neighborNodeEle.appendChild(neighborNodeIDEle);        
        
        // IPaddress
        Element neighborNodeIPaddressEle = doc.createElement("Neighbor:Node:IPaddress");
        Text neighborNodeIPaddressText = doc.createTextNode(this.node.getNodeIPaddress());
        neighborNodeIPaddressEle.appendChild(neighborNodeIPaddressText);
        neighborNodeEle.appendChild(neighborNodeIPaddressEle);        
        
        // Port
        Element neighborNodePortEle = doc.createElement("Neighbor:Node:Port");
        Text neighborNodePortText = doc.createTextNode(Integer.toString(this.node.getNodePort()));
        neighborNodePortEle.appendChild(neighborNodePortText);
        neighborNodeEle.appendChild(neighborNodePortEle);
        
        rootEle.appendChild(neighborNodeEle);
        
        // Rank
        Element neighborRankEle = doc.createElement("Neighbor:Rank");
        Text neighborRankText = doc.createTextNode(Integer.toString(this.rank));
        neighborRankEle.appendChild(neighborRankText);
        rootEle.appendChild(neighborRankEle);        
        
        doc.appendChild(rootEle);                
        
        return doc;
    }    
    
    public String toXMLString() throws Exception {
        String result = null;
        
        XMLTools xt = new XMLTools();                
        result = xt.writeXMLString(this.toXMLDoc());
        
        return result;
    }
    
    public void toXMLFile(String fileName) throws Exception {
        // Prepare the DOM document for writing
        Source source = new DOMSource(this.toXMLDoc());

        // Prepare the output file
        File file = new File(fileName);
        Result result = new StreamResult(file);

        // Write the DOM document to the file
        Transformer xformer = TransformerFactory.newInstance().newTransformer();
        xformer.transform(source, result);
    }
    
    public Neighbor fromXMLDoc(Document dom) {
        Neighbor result = new Neighbor();
        PeerNode neighborNode = new PeerNode();
        
        Element rootEle = dom.getDocumentElement();
        
        if (rootEle.getTagName().equals("Neighbor")) {
            NodeList neighborNodeList = rootEle.getElementsByTagName("Neighbor:Node");
            
            NodeList neighborNodeIDList = rootEle.getElementsByTagName("Neighbor:Node:ID");
            String neighborNodeIDText = neighborNodeIDList.item(0).getFirstChild().getNodeValue();
            NodeList neighborNodeIPaddressList = rootEle.getElementsByTagName("Neighbor:Node:IPaddress");
            String neighborNodeIPaddressText = neighborNodeIPaddressList.item(0).getFirstChild().getNodeValue();
            NodeList neighborNodePortList = rootEle.getElementsByTagName("Neighbor:Node:Port");
            String neighborNodePortText = neighborNodePortList.item(0).getFirstChild().getNodeValue();
            
            neighborNode.setNodeID(neighborNodeIDText);
            neighborNode.setNodeIPaddress(neighborNodeIPaddressText);
            neighborNode.setNodePort(Integer.valueOf(neighborNodePortText));
            
            NodeList neighborRankList = rootEle.getElementsByTagName("Neighbor:Rank");
            String neighborRankText = neighborRankList.item(0).getFirstChild().getNodeValue();
            
            result.setNode(neighborNode);
            result.setRank(Integer.valueOf(neighborRankText));
        }
                
        return result;
    }
    
    public Neighbor fromXMLString(String data) throws Exception {
        Document dom = null;
        XMLTools xt = new XMLTools();
        Neighbor result = null;
        
        // Parse the XML stream input to Document type
        dom = xt.db.parse(new InputSource(new StringReader(data)));
        
        result = fromXMLDoc(dom);
        
        return result;
    }
    
    public Neighbor fromXMLFile(String fileName) throws Exception {
        Document dom = null;
        File file = null;
        Neighbor result = null;
        XMLTools xt = new XMLTools();
        
        // Parse the XML stream input to Document type
        file = new File(fileName);
        dom = xt.db.parse(file);
        
        result = fromXMLDoc(dom);
        
        return result;
    }
    
//    public static void main(String[] args) throws Exception {
//        Node n1 = new Node();
//        n1 = n1.fromXMLFile("n1.xml");
//        
//        Neighbor b1 = new Neighbor(n1, 1);
//        
//        System.out.println(b1.toXMLString());
//        b1.toXMLFile("b1.xml");
//        
//        Neighbor b2 = new Neighbor();
//        b2 = b2.fromXMLFile("b1.xml");
//        b2.toXMLFile("b2.xml");
//    }
}
